package com.wes.dsptest.dspcontrol;

import static android.content.Context.BIND_AUTO_CREATE;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import cn.flyaudio.dsp.IdspInterface;
import cn.flyaudio.dsp.onVolumeAdcListener;

/**
 * desc:  ac8015 内置DSP的接口控制
 * author: CWP
 * date: 2021/10/09
 * commit: 目前8015需要注意问题：1 Speaker/Lineout/HeadSet对应DSP接口与实际播放不匹配。 2 Speaker/Lineout/HeadSet音量控制无法调节MIC音量
 */
public class YgInsideDSPControl {
    private static final String TAG = "YgInsideDSP";

    private static IdspInterface mdspInterface;
    private static boolean mIsDspControlBound = false;
    private static ServiceConnection dspSC = null;
    private static byte mFisrtNoSet = 0;      //第一次设置问题   0 - 未设置第一次数据    1 - 设置了第一次数据未成功   2 - 设置第一次数据成功

    private static int mMicAdc0Vol = 0;       //MicADC输入db值        范围0 - 43  默认0
    private static int mMicVol = 0;          //Mic输出音量           范围0 - 99
    private static int mMicDymVol = 0;          //Mic音量跟随其他输出通道
    private static int mLineOutVol = 0;          //line out
    private static int mSpeakerVol = 0;          //Speaker
    private static int mHeadsetVol = 0;          //Headset

    public static final int BAND_NUM = 3;
    public static final int BAND1 = 0;
    public static final int BAND2 = BAND1 + 1;
    public static final int BAND3 = BAND1 + 2;

    private static int mBandGain[] = new int[BAND_NUM];          //band gain           范围-150 - 150


    private static int inputGain = 0;     //0x7FFFFFFF = 0dB
    private static int fbGain = 0;        //0x7FFFFFFF = 0dB
    private static int maxDelay = 0;                //0x4F = 103ms
    private static int nLpRDelay = 0;
    private static int pLnRDelay = 0;
    private static int pLpRDelay = 0;

    private static Intent mIntent = null;

    private static Context mcontext;


    private static onVolumeAdcListener mAdcListener;
    private static int mCurADC0_val = 0;
    private static int mCurADC1_val = 0;

    /**
     * desc:  初始化连接dsp服务接口
     * author: CWP
     * date: 2021/10/09
     */
    public static boolean initDSP(Context context, IdspCallBack callBack) {
        mcontext = context;
        //ac8015
        if (mIntent != null)
            return mIsDspControlBound;

        mIntent = new Intent();
        mIntent.setComponent(new ComponentName("cn.flyaudio.dsp", "cn.flyaudio.dsp.DspService"));
        getConfigFromDb();

        mAdcListener = new onVolumeAdcListener.Stub() {
            @Override
            public void onAdc0(float adc) throws RemoteException {
                int vol = adcToVolume(adc, 0);
                callBack.adcToMicVol(adc, vol);
                Log.i(TAG,"adcListener adc0:" + adc + " headset vol:" + vol);
            }

            @Override
            public void onAdc1(float adc) throws RemoteException {
                int vol = adcToVolume(adc, 1);
                callBack.adcToHeadSetVol(adc, vol);
                Log.i(TAG,"adcListener adc1:" + adc + " mic vol:" + vol);
            }
        };

        dspSC = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                mdspInterface = IdspInterface.Stub.asInterface(iBinder);
                callBack.connectServerCallBack(mdspInterface);
                Log.i(TAG,"dspinterface onServiceConnected!");
                //如果未设置成功重新设置
                if (mdspInterface != null) {
                    mFisrtNoSet = 2;
                    mMicAdc0Vol = 0;
                    setMICInVol(mMicAdc0Vol);
                    setRecordOutVol(mMicVol);
                    setLineOutVol(mLineOutVol);
                    setSpeakerVol(mSpeakerVol);
                    setHeadsetVol(mHeadsetVol);
                    setMICEQ(BAND1, mBandGain[BAND1]);      //80Hz
                    setMICEQ(BAND2, mBandGain[BAND2]);      //800Hz
                    setMICEQ(BAND3, mBandGain[BAND3]);      //3000Hz
                    setMICBPF(0, 24000);
                    SetReverbUser(inputGain, fbGain, maxDelay);
                    Log.i(TAG,"dspinterface mMicAdc0Vol：" + mMicAdc0Vol + " mMicVol:" + mMicVol + " mLineOutVol:" + mLineOutVol + " mSpeakerVol:" + mSpeakerVol + " mHeadsetVol:" + mHeadsetVol);
                    Log.i(TAG,"dspinterface band 80Hz 800Hz 3KHz val：" + mBandGain[BAND1] + " " + mBandGain[BAND2] + " " + mBandGain[BAND3]);

                    try {
                        mdspInterface.registerVolumeAdcCallback(mAdcListener);

                        //获取当前adc值
                        Log.i(TAG,"get current adc0:" + mdspInterface.getAdc0());
                        Log.i(TAG,"get current adc1:" + mdspInterface.getAdc1());

                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                Log.i(TAG,"dspinterface onServiceDisconnected!");
                mdspInterface = null;
            }
        };
        mIsDspControlBound = context.bindService(mIntent, dspSC, BIND_AUTO_CREATE);
        Log.i(TAG,"dspinterface bindService!" + mIsDspControlBound);

        return mIsDspControlBound;
    }

    /**
     * 设置默认参数
     */
    private static void getConfigFromDb() {
//        BasicParamBean basicParamBean = SQLManager.findFirst(BasicParamBean.class, true);
//        RecordOutputParamBean recordoutParamBean = SQLManager.findFirst(RecordOutputParamBean.class, true);
//        ReverberationParamBean reverberationParamBean = SQLManager.findFirst(ReverberationParamBean.class, true);
//        if (basicParamBean != null) {
//            mMicVol = basicParamBean.getMicInputVolume();
//            mHeadsetVol = basicParamBean.getEarphoneOutputVolume();
//            mSpeakerVol = basicParamBean.getSpeakerVolume();
//            mLineOutVol = basicParamBean.getSpeakerVolume();
//        }
//        if (recordoutParamBean != null) {
//            mBandGain[BAND1] = recordoutParamBean.getMicEq110Hz() + 24;
//            mBandGain[BAND2] = recordoutParamBean.getMicEq330Hz() + 24;
//            mBandGain[BAND3] = recordoutParamBean.getMicEq800Hz() + 24;
//        }
//        if (reverberationParamBean != null) {
//            inputGain = reverberationParamBean.getReverberationVolume();
//            fbGain = reverberationParamBean.getRevVolume();
//            maxDelay = reverberationParamBean.getReverberationDuration();
//        }
    }

    public static void shutdown()
    {
        Log.i(TAG,"dspinterface shutdown mdspInterface："+mdspInterface);
        if(mdspInterface != null)
        {
            try {
                mdspInterface.onShutdown(0);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * adcToVolume
     * adc转换为音量值
     *
     * @author cwp
     * @time 2022/9/13
     */
    public static int adcToVolume(float adc, int ADCChannel) {
        int vol = 0;
        int ADCVal = (int) adc; //接口未处理小数
        int adcRipple = 54; // 纹波阈值
        int curADC = (ADCChannel == 0) ? mCurADC0_val : mCurADC1_val;
        int adcRip = Math.abs(ADCVal - curADC);

        // adc 低于1000 纹波小

        //normal 4096
        //实际机器adc最大范围在3820——3906，软件判断最大3800
//        Log.i(TAG," adc curADC:" + curADC + "ADCVal:"+ ADCVal);
        if (ADCVal <= 4096 && ADCVal >= 0) {
            if (ADCVal < 1500)  //对应vol = 40
            {
                if (adcRip > adcRipple / 2) {
                    curADC = ADCVal;
                }

            } else if (ADCVal < 3800) {
                if (adcRip > adcRipple) {
                    curADC = ADCVal;
                }
            } else {
                curADC = 3800;
            }


            if (ADCChannel == 0) {
                mCurADC0_val = curADC;
                if (curADC < 1500) {
                    vol = (int) (curADC * 40) / 1500;
                } else
                    vol = (int) ((curADC - 1500) * 60) / 2300 + 40;
            } else {
                mCurADC1_val = curADC;
                if (curADC < 2800) {
                    vol = (int) (curADC * 40) / 2800;
                } else
                    vol = (int) ((curADC - 2800) * 60) / 1000 + 40;
            }
        }
        return vol;

    }

    //mic
    public static void setMICBPF(int start, int end) {

        if (mdspInterface == null) {
            Log.i(TAG,"setMICBPF mdspInterface null!!! ");
            return;
        }

        try {

            //start = 0 end = 24000 表示关闭
            if (start < end && (start >= 0) && (end <= 24000)) {
                Log.i(TAG,"setMICBPF mdspInterface start:" + start + " end:" + end);
                mdspInterface.onMic_BPF(start, end);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    //mic 硬件adc音量调节  ，该接口暂时不需要使用
    public static void setMICInVol(int vol) {
        mMicAdc0Vol = vol;
        int db = (vol * 43) / 99;
        if (mdspInterface == null) {
            Log.i(TAG,"setMICInVol mdspInterface null!!! ");
            return;
        }
        //输入范围为0 —— 99

        try {

            Log.i(TAG,"setMICInVol mdspInterface db:" + db);
            //范围0 - 43 db
            if (db >= 0 && db <= 43)
                mdspInterface.onAdc0_vol(db);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    //mic 音量调节
    public static void setRecordOutVol(int vol) {

        mMicVol = vol;
        if (mdspInterface == null) {
            Log.i(TAG,"setRecordOutVol mdspInterface null!!! ");
            return;
        }
        //输入范围为0 —— 99
        // 1 - 99:  -10 —— 20DB
        // 0 = -102
        //20220415 修正记录 实际接口调节范围提高12dB   为 2 —— 32dB   ，24dB开始会有消顶，所以整体减少8dB
        int db = (vol * 30) / 99 + 2;
        if (db > 20) {
            db = db * 3 / 4;
        }

        //音量最低，也出mic 声音
        if (vol == 0)
            db = -102;

        try {
            Log.i(TAG,"setRecordOutVol mdspInterface db:" + db);
            //范围-102 - 84 db
            if (db >= -102 && db <= 84)
                mdspInterface.onMic_vol(db);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }


    public static void setLineOutVol(int vol) {
        mLineOutVol = vol;
        if (mdspInterface == null) {
            Log.i(TAG,"setLineOutVol mdspInterface null!!! ");
            return;
        }
        //输入范围为0 —— 99
        // 1 - 99:  -19 —— 30dB
        // 0 = -102
        double idB = 10.034f * (Math.log((double) vol) / Math.log(2.71828182845)) - 40.356f;
        //y = 10.034ln(x) - 43.067
        //-41.1dB——5dB范围 音量曲线公式
        int db = (vol == 0) ? -102 : (int) idB;

        try {

            Log.i(TAG,"setLineOutVol mdspInterface db:" + db);
            //范围-102-84 db
            //Speaker 接口实际控制的是Line out
            if (db >= -102 && db <= 84) {
                mdspInterface.onLineOut_post_vol(db);
//                mdspInterface.onLineOut_vol(db);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public static void setSpeakerVol(int vol) {
        mSpeakerVol = vol;
        if (mdspInterface == null) {
            Log.i(TAG,"setSpeakerVol mdspInterface null!!! ");
            return;
        }
        //输入范围为0 —— 99  mic 75  headset 42 最大
        // 1 - 99:  -19 —— 30DB     改为-40 - 1db
        // 0 = -102
        double idB = 10.034f * (Math.log((double) vol) / Math.log(2.71828182845)) - 40.356f;
        //y = 10.034ln(x) - 43.067
        //-41.1dB——5dB范围 音量曲线公式
        int db = (vol == 0) ? -102 : (int) idB;

        try {

            Log.i(TAG,"setSpeakerVol mdspInterface db:" + db);
            //范围-102-84 db
            //Headset 接口实际控制的是Speaker
            if (db >= -102 && db <= 84) {
//                mdspInterface.onSpeaker_vol(db);
                mdspInterface.onSpeaker_post_vol(db);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public static void setHeadsetVol(int vol) {
        mHeadsetVol = vol;
        if (mdspInterface == null) {
            Log.i(TAG,"setHeadsetVol mdspInterface null!!! ");
            return;
        }
        double idB = 10.034f * (Math.log(vol) / Math.log(2.71828182845)) - 40.356f;
        int db = (vol == 0) ? -102 : (int) idB;
        try {
            Log.i(TAG,"setHeadsetVol mdspInterface db " + db + " idB:" + idB + "vol:" + vol);
            //范围-102-84 db
            //line out 接口实际控制的是耳机headset
            if (db >= -102 && db <= 84) {
                //mdspInterface.onHeadSet_vol(db);
                mdspInterface.onHeadSet_post_vol(db);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**
     * ac8015主板上应用静默安装
     */
    public static void installAPP(String path, String packageName) {
        if (mdspInterface == null) {
            Log.e(TAG,"installAPP mdspInterface null!!! ");
            return;
        }

        try {

            Log.i(TAG,"installAPP mdspInterface path:" + path + "  package name:" + packageName);
            if ((path != null) && (packageName != null)) {
                mdspInterface.installapp(path, packageName);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    //修改 gain范围需在0——36
    public static void setMICEQ(int band, int gain) {
        if (band < BAND_NUM) {
            //对应版本 -15dB到12dB 对应UI刻度
            mBandGain[band] = 10 * (gain - 24);
            //因为不改UI，换算范围对应UI -24dB到12dB
            if (mBandGain[band] < 0) {
                //-240 —— 0 换算为-150dB —— 0
                mBandGain[band] = (mBandGain[band] * 150) / 240;

                //接口参数范围-15 —— 15dB   步进0.1dB
                if (mBandGain[band] < -150)
                    mBandGain[band] = -150;
            } else {   //0 —— 120 换算 0 —— 150dB
                mBandGain[band] = (mBandGain[band] * 150) / 120;
                if (mBandGain[band] > 150)
                    mBandGain[band] = 150;
            }
        } else {
            Log.e(TAG,"setMICEQ Band overflow !!! " + band);
        }
        if (mdspInterface == null) {
            Log.i(TAG,"setMICEQ mdspInterface null!!! ");
            return;
        }
        //输入范围为0 —— 99

        try {
            Log.i(TAG,"setMICEQ mdspInterface db:" + mBandGain[band]);

            if (band == 0) {
                mdspInterface.onMic_EQ(1, 80, 200, mBandGain[band]);
            } else if (band == 1) {
                mdspInterface.onMic_EQ(2, 800, 200, mBandGain[band]);
            } else if (band == 2) {
                mdspInterface.onMic_EQ(3, 8000, 200, mBandGain[band]);
            } else
                Log.i(TAG,"Mic EQ band error");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    //    暂屏蔽，跟随方式由framework或dsp接口实现
//    private int micRateflowerOutput(int curMicDymVol, int oldDestVol, int destVol)
//    {
//        int outMicVol = 0;
//        Log.i(TAG, "output before: " + curMicDymVol + " oldDestVol:" + oldDestVol + " Vol:" + destVol);
//        //范围为0-99
//        if(destVol != 0)
//        {
//            if(oldDestVol > destVol) //音量调小
//            {
//                // 判断 mic 当前到0的范围
//                if(curMicDymVol > 0)
//                {
//                    outMicVol = ((oldDestVol - destVol)*curMicDymVol)/(oldDestVol*2);
//                    outMicVol = (curMicDymVol - outMicVol/2);
//                    if(outMicVol < 1)  //防止过低mute
//                        outMicVol = 1;
//                    //设置MIC音量
//                    setRecordOutVol(outMicVol);
//                }
//            }
//            else if(oldDestVol < destVol) //音量调大
//            {
//
//                outMicVol = ((destVol - oldDestVol)* (100 - curMicDymVol))/((100 - oldDestVol)*2);
//                outMicVol += curMicDymVol;
//                if(outMicVol > 99)
//                    outMicVol = 99;
//                //设置MIC音量
//                setRecordOutVol(outMicVol);
//            }
//        }
//        else
//        {
//            outMicVol = 0;
//           setRecordOutVol(outMicVol);
//        }
//
//        Log.i(TAG, "micRateflowerOutput: " + outMicVol + " oldDestVol:" + oldDestVol + " Vol:" + destVol);
//        return  outMicVol;
//    }


    public static void SetReverbUser(int inGain, int fbg, int delay) {
        Log.i(TAG,"SetReverbUser  cmd[6]:" + inGain + " cmd[7]:" + fbg + " cmd[8]:" + delay);
        long temp = 0;
        temp = (long) inGain * 0x7FFFFFFF;
        Log.i(TAG,"SetReverbUser  temp:" + temp);
        inputGain = (int) (temp / 99);
        temp = (long) fbg * 0x7FFFFFFF;
        Log.i(TAG,"SetReverbUser  temp:" + temp);
        fbGain = (int) (temp / 99);
        if (delay <= 0x4F)
            maxDelay = delay;
        if (mdspInterface == null) {
            Log.i(TAG,"SetReverbUser mdspInterface null!!! ");
            return;
        }
        //输入范围为0 —— 99

        try {
            //live max = 0x29  nlpR = 0x1F pLnR = 0x17 pLpR = 0x0d

            int nLpRDelay = (maxDelay * 0x1F) / 0x29;
            int pLnRDelay = (maxDelay * 0x17) / 0x29;
            int pLpRDelay = (maxDelay * 0x0d) / 0x29;

            Log.i(TAG,"SetReverbUser mdspInterface db:" + inputGain + " fbGain:" + fbGain + " max:" + maxDelay + " nLpR:" + nLpRDelay + " pLnR:" + pLnRDelay + " pLpR:" + pLpRDelay);
            mdspInterface.onMic_reverbUser(inputGain, fbGain, maxDelay, nLpRDelay, pLnRDelay, pLpRDelay);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param mode 1:k歌模式  0:朗读模式
     */
    public static void onKTVAudioRecordMode(int mode) {
        if (mdspInterface != null) {
            try {
                mdspInterface.onKTVAudioRecordMode(mode);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    public static void onKillApp(String packageName) {
            if (mdspInterface != null) {
                try {
                    mdspInterface.killApp(packageName);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

        }
    }

    public static void CloseDSP() {
        try {
            if (mIsDspControlBound || mdspInterface != null) {
                Log.i(TAG,"DSP control unbind!!!\r\n");
                mdspInterface.unregisterVolumeAdcCallback(mAdcListener);
                mcontext.unbindService(dspSC);
                mIsDspControlBound = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }
    }

}
